Clarify tool result content visibility#1562
Conversation
…ent vs. structuredContent semantics and add decoupled-fields sample
…ot full CallToolResult) when StructuredContent is also present
|
@mikekistler can you help review this PR? |
mikekistler
left a comment
There was a problem hiding this comment.
This appears to be almost entirely a documentation change. It seems fine but I'm not sure all of this is needed.
In addition, I think we should hold off on merging this until SEP-2200 is accepted.
|
@mikekistler
That makes landing this PR awkward in every direction as the changes all normatively cite SEP-2200, which is now incorrect guidance. I'd lean toward closing this PR and leaving #1552 open to track the future polymorphic-return-types work. Does that match your read, or do you see a scoped subset (e.g. just the XML docs changes) worth keeping? |
|
I also prefer simply closing this PR and waiting until the dust settles on whatever guidance is deemed appropriate. |
feat(sep-2200): align tool result content visibility with SEP-2200
Closes #1552
Summary
Brings the C# SDK into compliance with SEP-2200 — "Clarify tool result content visibility"
SEP-2200 clarifies that
CallToolResult.contentis model-oriented (may be a prose summary) andCallToolResult.structuredContentis machine-oriented (strict JSON for programmatic consumers). Clients SHOULD prefercontentfor model context and SHOULD NOT forward both fields verbatim to the LLM. The wire format is unchanged.What
Behavioural fix
McpClientTool.InvokeCoreAsyncRemoved
result.StructuredContent is nullfrom the gate. The Content-block conversion path now triggers whenever there's no protocol-level info to preserve (IsError=trueor non-emptyMeta), regardless of whetherStructuredContentis also set.See THIS comment for more info.
XML doc updates (no behaviour change)
CallToolResult.Content/StructuredContent— model-vs-machine semantics + the SEP-2200 selection rule.[McpServerTool].UseStructuredContent/OutputSchemaType— call out the default JSON-dump behaviour and point to the recommended decoupled-fields pattern.McpServerToolCreateOptions.UseStructuredContent/OutputSchema— same wording mirrored on the options surface.McpClient.CallToolAsync—<remarks>explaining which field to forward to the model and which to consume programmatically.### Sample
New
samples/EverythingServer/Tools/WeatherStructuredTool.csdemonstrating the SEP-2200 recommended pattern: returns aCallToolResultwith model-friendly prose inContent("It's 72°F and sunny in Paris …") alongside machine-friendly JSON inStructuredContent({"city":"Paris","tempF":72,…}), with the schema advertised viaOutputSchemaType = typeof(WeatherReading).Behavioural change call-out
Clients embedding this SDK in
IChatClientflows will stop double-feedingcontent+structuredContentto the LLM.The default
[McpServerTool(UseStructuredContent=true)]JSON-dump-into-both shape is preserved (SEP-2200 explicitly permits it, though considers it suboptimal).No wire change
SEP-2200 itself is non-wire-breaking: same
content, samestructuredContent, same types. Only the SDK's consumption of the wire result changed.Test plan
dotnet test tests/ModelContextProtocol.Tests(net10.0): 1887 passed, 0 failed, 5 skipped.StructuredContentTool_PrefersContentBlocksForModeldotnet build src/ModelContextProtocol.Coreanddotnet build samples/EverythingServer: 0 warnings, 0 errors across all target frameworks.